﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Dapper;
using System.Configuration;
using log4net;

namespace Himp.Platform.Client
{
    /// <summary>
    /// 归样成功后转制样码
    /// </summary>
    public class SampleCodeGenerateWorker
    {
        #region SQL

        public const string GET_QRCODE_SQL = @"
            SELECT [一次编号]
            FROM [dbo].[收样明细表]
            WHERE 时间 = FORMAT(GETDATE(), 'yyyy-MM-dd')
            ";

        public const string EXIST_FLAG_SQL = @"
            SELECT CASE WHEN 
            EXISTS (SELECT 1 FROM [TaskScheduling].[TS_SamplePreparationTasks] WHERE Id = @Id) 
            THEN 1 
            ELSE 0 
            END";

        public const string INSERT_SAMPLE_PREPARATION = @"
            INSERT INTO
            [TaskScheduling].[TS_SamplePreparationTasks]
            (
            Id,
            SampleCode,
            TaskAssgnTime,
            LastOperTime,
            ExecStas
            )
            VALUES
            (
            @Id,
            @SampleCode,
            GETDATE(),
            GETDATE(),
            @ExecStas
            )
            ";

        #endregion

        #region 字段

        //private readonly ConnectionStringOption _connectionStrings;
        private static readonly ILog log = LogManager.GetLogger(typeof(SampleCodeGenerateWorker));

        #endregion

        #region 方法

        private Timer _timer;
        private readonly TimeSpan _interval = TimeSpan.FromMilliseconds(60000);
        private readonly TimeSpan _delay = TimeSpan.FromMilliseconds(0);
        private bool _isExecuting = false;
        private static readonly object _lock = new object();
        private bool _init = false;

        public SampleCodeGenerateWorker()
        {
            // 初始化计时器，初始时不启动，等待 StartAsync 启动
            //_timer = new Timer(ExecuteJob, null, _delay, Timeout.InfiniteTimeSpan);
            //_timer.Change(_delay, _interval);
            //_init = true;
            //_connectionStrings = connectionStrings.Value;
        }

        private async void ExecuteJob(object state)
        {
            if (_isExecuting || !_init)
            {
                // 如果任务正在执行，则跳过
                return;
            }

            lock (_lock)
            {
                if (_isExecuting)
                {
                    return;
                }
                _isExecuting = true;
            }

            try
            {
                // 你的任务逻辑
                await StartAsync(new CancellationToken());

            }
            catch (Exception e)
            {
                await Console.Out.WriteLineAsync(e.Message);
            }
            finally
            {
                GC.Collect(0);
                lock (_lock)
                {
                    _isExecuting = false;
                }
                // 任务完成后重新设置计时器
                _timer.Change(_interval, Timeout.InfiniteTimeSpan);
            }
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            // 从源数据库读取数据
            IEnumerable<string> data = ReadQrCode();
            // 将数据写入目标数据库
            await QrCodeToSampleCode(data);
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IEnumerable<string> ReadQrCode()
        {
            try
            {
                string connectionString = ConfigurationManager.AppSettings["CoalManager"];
                using (IDbConnection connection = new SqlConnection(connectionString))
                {
                    connection.Open();
                    // 读取数据
                    var qrCodeList = connection.Query<string>(GET_QRCODE_SQL);

                    return qrCodeList;
                }
            }
            catch (Exception e)
            {
                log.Error(e);
            }

            return Enumerable.Empty<string>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task QrCodeToSampleCode(IEnumerable<string> data)
        {
            try
            {
                string connectionString = ConfigurationManager.AppSettings["DefaultConnect"];

                using (IDbConnection connection = new SqlConnection(connectionString))
                {
                    connection.Open();

                    foreach (var qrCode in data)
                    {
                        await Console.Out.WriteLineAsync(qrCode);
                        // 检查 ID 是否已存在
                        bool exists = await connection.ExecuteScalarAsync<bool>(EXIST_FLAG_SQL,
                            new { Id = qrCode });

                        if (!exists)
                        {
                            CodeConversionManager codeConversionManager = new CodeConversionManager();
                            var samplingResult = codeConversionManager.GenerateSamplingNo(qrCode, MainWindow.UserName);
                            var sampleCode = qrCode;

                            if (samplingResult.Item1)
                            {
                                sampleCode = samplingResult.Item2;
                            }

                            var codeStas = await connection.ExecuteAsync(INSERT_SAMPLE_PREPARATION,
                                new
                                {
                                    Id = qrCode,
                                    SampleCode = sampleCode,
                                    ExecStas = "就绪"
                                });
                            await Console.Out.WriteLineAsync($"{qrCode}:{codeStas}");
                        }
                        else
                        {
                            await Console.Out.WriteLineAsync($"{qrCode}:已添加");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                log.Error(e);
            }
        }

        #endregion
    }
}
